home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-07
/
book.exe
/
LANLIB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-22
|
9KB
|
395 lines
/*
//
// LANLIB.C Common routines called by both LAN and LANRES
//
// (c) Copyright 1991 Adrian King.
//
//
// This code was developed for inclusion in the book
// "Running LANtastic", by Adrian King, published by
// Bantam Books, October 1991.
//
// This product uses the TesSeRact(tm) Ram-Resident Library and
// supports the TesSeRact Standard for Ram-Resident Program Comm-
// unication. For information about TesSeRact, contact the TesSeRact
// Development Team at:
//
// TesSeRact Development Team
// 1657 The Fairways
// Suite 101
// Jenkintown PA 19046
// 1-215-884-3373
//
// Compuserve: 70731,20
// MCIMAIL: 315-5415
//
// $Header: C:/USR/LANBOOK/SRC2/LAN/VCS/LANLIB.C_V 1.1 22 Sep 1991 9:16:24 $
//
// $Log: C:/USR/LANBOOK/SRC2/LAN/VCS/LANLIB.C_V $
//
// Rev 1.1 22 Sep 1991 9:16:24
//Added correct TesSeRact copyright notice.
//
// Rev 1.0 13 Jul 1991 11:19:38
//Initial revision.
//
*/
// Standard DOS includes
#include "string.h"
#include "time.h"
#include "dos.h"
// NOS specific includes
#include "nos.h"
#include "noslib.h"
#include "lan.h"
// Version specific stuff
// Needed for TesSeRact
#include "tess.h"
WORD TSRid; // Will hold TesSeRact id number
char *TSRIdStr = "A.KING01"; // TesSeRact id string
// Global external data
// Global data held in this module
//
// Error messages indexed by error numbers.
// No checking is performed. The callers are
// trusted to get it right.
//
char *LANerr[] = {
"", // 0 is not used
"LANRES module not loaded",
"LANRES module already loaded",
"No interrupt vector available",
"NETBIOS not loaded",
"NOS not loaded",
"Unable to get machine name",
"Error in NOS_Get_Msg_Vector",
"Error in NOS_Set_Msg_Flag",
"Error in NOS_Set_Msg_Vec",
"No NETBIOS NCBs left to allocate",
"No LAN software loaded",
"No network host name specified",
"Error in NOS_Get_Msg_Flag",
"Error trying to go resident",
"No machine name defined",
"Error in NOSGetDOSVector",
"Error in NOSSetDOSVector",
"Error sending network message",
(char *)0 // Place holder
};
struct lannode lannode[D_NODES]; // Table of active nodes.
char cpNRSL[] = "----"; // Says what's loaded on this node
//
// FATAL
//
// Report fatal error and quit
//
void FATAL(N)
int N;
{
NOSperror(LANerr[N]);
#ifdef __TURBOC__
_exit(N);
#endif
#ifndef __TURBOC__
exit(N);
#endif
}
//
// SENDMESSAGE
//
// Send a message block to the named host using the NOS message
// service.
//
// Called with:
//
// m is a message buffer to use
// host is name of destination host
// msgtype is type of message to send
// msgtext is array of bytes to send as message text field
// msglen is -1 if text is already in buffer, or is the #
// of bytes to send
//
int sendmessage(m, host, msgtype, msgtext, msglen)
struct message_buffer *m;
char *host;
int msgtype;
char *msgtext;
int msglen;
{
int i;
m->MB_type = msgtype; // Set message type
// And destination host name
for (i = 0; i < D_NAMESZ; i++)
m->MB_machine[i] = host[i];
// and set others to null strings
m->MB_server[0] = m->MB_user[0] = '\0';
if (msglen != -1){ // Need to copy in the string?
for (i = 0; i < msglen; i++)
m->MB_text[i] = msgtext[i];
for (i = msglen; i < MB_textlen; i++) // Space fill the rest
m->MB_text[i] = ' ';
}
#ifdef BACKGROUND
msgstats.out++; // Update transmission count
#endif
return NOSSendMsg(m);
}
//
// LANLIBCHECK
//
// Make sure we can communicate with the resident library.
// Abort if we cannot.
//
void lanlibcheck()
{
//
// This will only ever be called by the foreground LAN program
//
if (TsCheckResident((char far *)TSRIdStr, (unsigned far *)&TSRid) == 0)
FATAL(E_NOLANLIB);
}
#ifndef __TURBOC__
//
// DELAY
//
// Delay by looping for a specified time
// Turbo C has this as a library routine.
//
void delay(nMSecs)
unsigned nMSecs;
{
time_t T, tEnd;
time(&T);
tEnd = T + ((time_t)nMSecs/1000);
while (T < tEnd)
time(&T);
}
#endif
//
// COPYFARTONEAR
//
// Copy a FAR buffer to a NEAR place
//
void copyfartonear(fpM, cpM, n)
char far *fpM;
char *cpM;
int n;
{
int i;
for (i=0; i < n; i++)
*cpM++ = *fpM++;
}
//
// INITNODETABLE
//
// Initialize the network node table so that all entries are
// empty.
//
void initnodetable()
{
int i;
for (i = 0; i < D_NODES; i++)
lannode[i].cpName[0] = '\0';
}
//
// REFRESHNAMES
//
// Update the table of nodes currently active on the LAN
//
void refreshnames()
{
int i;
struct message_buffer M;
char *cpM = "Status enquiry";
// Send a broadcast that causes every node on the network to
// respond. The entry in the lannode table for the responding
// machine will be updated when the reply comes in.
//
// Only nodes running LANRES will know how to respond to the
// enquiry message. Others will simply put it up on the screen
// as an unsolicited message.
//
// Should really also have a timer that goes off and causes us
// to send a status request broadcast. If there is no response,
// then we should assume that the node has gone away and its
// entry won't get re-instated.
//
//
// First empty the current background node table.
// Call LANRES via the TesSeRact library. Pass in a zero
// value to denote the node table should be cleared.
//
(void)TsCallUserProc(TSRid, (void far *)0);
// Ask for status network wide
if (sendmessage(&M, "", MBT_LANstatus, cpM, strlen(cpM)) == -1)
NOSprintstr("refreshnames() sendmessage error\n");
}
//
// ADDNAME
//
// Add or update the name of a LAN node in the global table
//
int addname(cpS, n)
char *cpS; // Points to name. May not be null terminated.
int n; // Flags (same as NOSPresence returns.)
{
int i;
char *cp;
cp = cpS;
while (*cp){
if (*cp == ' ')
*cp = '\0'; // Null terminate the name
cp++;
}
for (i = 0; i < D_NODES; i++){
if (nodenamecmp(cpS, lannode[i].cpName) == 0){
// Names match, update flags word
lannode[i].wFlags = n;
return 0;
}
}
// Not present, add to table
for (i = 0; i < D_NODES; i++){
if (lannode[i].cpName[0] == '\0'){
// Found a free entry
cp = lannode[i].cpName; // Add to table
while ((*cp++ = *cpS++) != '\0')
;
lannode[i].wFlags = n;
return 0; // Say okay
}
}
return -1; // Table full - "cannot happen"
}
//
// NODENAMECMP
//
// Compare two node names. Comparison is case insensitive
// and trailing spaces are not significant. Return 0 if
// names match, non-zero if not (like strcmpX().)
//
nodenamecmp(cp1, cp2)
char *cp1, *cp2;
{
char *cp;
// Put a null on trailing spaces
cp = strchr(cp1, ' ');
if (cp != NULL)
*cp = '\0';
cp = strchr(cp2, ' ');
if (cp !=NULL)
*cp = '\0';
return strcmpi(cp1, cp2);
}
//
// GENNRSL Generate NRSL string from current machine status flags
//
void gennrsl()
{
int i;
i = NOSPresence(); // Get flags and set up string
cpNRSL[0] = 'N'; // LANBIOS must be running
cpNRSL[1] = (i&D_redir)?'R':'-';
cpNRSL[2] = (i&D_server)?'S':'-';
cpNRSL[3] = (i&D_lanpup)?'L':'-';
lannode[0].wFlags = i; // Refresh the flags word (server may
// have been loaded later for example.)
}
//
// SIZEOFCODE
//
// Adapted from the example given in the TesSeRact documentation.
// We make sure that all of the requesting program stays in memory.
//
// Return from this function is the number of paragraphs to
// keep when going resident.
//
unsigned SizeOfCode()
{
#ifdef MSC5
unsigned int far *PSP; // far pointer to PSP
extern unsigned _psp, // segment of PSP
_atopsp; // undocumented offset of top of
// MSC 5.0 stack
#endif /* End of MSC5 */
#ifdef __TURBOC__
extern unsigned _psp, // segment address of PSP
__heapbase, // undocumented offset of base of
// Turbo C heap area
_heaplen, // size of heap
_stklen; // size of stack
#endif /* End of __TURBOC__ */
unsigned used; // variable to save paragraphs
struct SREGS sregs; // segment register structure
segread(&sregs); // read the segment regs
#ifdef __TURBOC__
used = (((__heapbase + 16 + _heaplen + _stklen) >> 4) + sregs.ds) - _psp;
#endif
#ifdef MSC5
FP_SEG(PSP) = _psp; // segment address of psp
FP_OFF(PSP) = 0; // offset of the psp is zero
used = *(PSP+1) - _psp; // number of paras used by program
#endif
return(used); // return number of paragraphs
}